package com.snow.service.content.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.snow.constant.ErrorConstant;
import com.snow.constant.Types;
import com.snow.constant.Webconst;
import com.snow.dao.CommentDao;
import com.snow.dao.ContentDao;
import com.snow.dao.RelationShipDao;
import com.snow.exception.SiteException;
import com.snow.pojo.dto.cond.ContentCond;
import com.snow.pojo.model.CommentDomain;
import com.snow.pojo.model.ContentDomain;
import com.snow.pojo.model.RelationShipDomain;
import com.snow.service.content.ContentService;
import com.snow.service.meta.MetaService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Type;
import java.util.List;

/**
 * @Description:
 * @author: snow
 * @Date: 2020-01-22
 **/
@Service
public class contentServiceImpl implements ContentService {
    @Autowired
    private MetaService metaService;
    @Autowired
    private ContentDao contentDao;
    @Autowired
    private CommentDao commentDao;
    @Autowired
    private RelationShipDao relationShipDao;
    @Override
    @Transactional
    @CacheEvict(value={"articleCaches","articleCache"},allEntries = true,beforeInvocation = true)
    public void updateCategory(String oldName, String newName) {
        ContentCond cond = new ContentCond();
        cond.setCategory(oldName);
        List<ContentDomain> articles = contentDao.getArticlesByCond(cond);
        if(articles != null){
            articles.forEach(article->{
                if(article != null){
                    article.setCategories(article.getCategories().replace(oldName,newName));
                    contentDao.updateArticleById(article);
                }
            });
        }
    }

    @Override
    @Cacheable(value="articleCache",key="'article_' + #p0")
    public ContentDomain getArticleById(Integer cid) {
        if(cid == null){
            throw SiteException.withErrorCode(ErrorConstant.Commons.PARAM_IS_EMPTY);
        }
        return contentDao.getArticle(cid);
    }

    @Override
    @CacheEvict(value={"articleCache","articleCaches"},allEntries = true,beforeInvocation = true)
    public int updateContentById(ContentDomain contentDomain) {
        if(contentDomain == null && contentDomain.getCid() != null){
            throw SiteException.withErrorCode(ErrorConstant.Commons.PARAM_IS_EMPTY);
        }
        return contentDao.updateArticleById(contentDomain);
    }

    /**
     * 添加文章,同时也要添加meta和relationship
     * @param contentDomain
     */
    @Override
    @Transactional
    @CacheEvict(value = {"articleCache","articleCaches"},allEntries = true,beforeInvocation = true)
    public void addArticle(ContentDomain contentDomain) {
        if(contentDomain == null){
            throw SiteException.withErrorCode(ErrorConstant.Commons.PARAM_IS_EMPTY);
        }
        if(StringUtils.isBlank(contentDomain.getTitle())){
            throw SiteException.withErrorCode(ErrorConstant.Article.TITLE_CAN_NOT_EMPTY);
        }
        if(contentDomain.getTitle().length() > Webconst.MAX_TITLE_WORDS){
            throw SiteException.withErrorCode(ErrorConstant.Article.TITLE_IS_TOO_LONG);
        }
        if(StringUtils.isBlank(contentDomain.getContent())){
            throw SiteException.withErrorCode(ErrorConstant.Article.CONTENT_CAN_NOT_EMPTY);
        }
        if(contentDomain.getContent().length() > Webconst.MAX_TEXT_WORDS){
            throw SiteException.withErrorCode(ErrorConstant.Article.CONTENT_TOO_LONG);
        }
        String tags = contentDomain.getTags();
        String categories = contentDomain.getCategories();
        contentDao.addArticle(contentDomain);
        Integer cid = contentDao.getNewArticleId();
        metaService.addMetas(cid,tags, Types.TAG.getType());
        metaService.addMetas(cid,categories,Types.CATEGORY.getType());

    }

    /**
     * 删除文章同时也要删除文章下的所有评论
     * @param cid
     */
    @Override
    @Transactional
    @CacheEvict(value={"articleCaches","articleCache"},allEntries = true,beforeInvocation = true)
    public void deleteArticleById(Integer cid) {
        if(cid == null){
            throw SiteException.withErrorCode(ErrorConstant.Commons.PARAM_IS_EMPTY);
        }
        contentDao.deleteArticleById(cid);
        List<CommentDomain> comments = commentDao.getCommentsByCId(cid);
        if(comments != null){
            comments.forEach(comment->{
                if(comment != null){
                    commentDao.deleteCommentById(comment.getCoid());
                }
            });
            //删除关联
            List<RelationShipDomain> relations = relationShipDao.getRelationshipBycId(cid);
            if(relations != null && relations.size()>0){
                relationShipDao.deleteRelationShipByCid(cid);
            }
        }
    }

    /**
     * 跟新文章评论数
     * @param contentDomain
     */
    @Override
    @Transactional
    @CacheEvict(value={"articleCache","articleCaches"},allEntries = true,beforeInvocation = true)
    public void updateArticleHits(ContentDomain contentDomain) {
        if(contentDomain != null && contentDomain.getHits() !=null){
            contentDao.updateArticleById(contentDomain);
        }else{
            throw SiteException.withErrorCode(ErrorConstant.Commons.PARAM_IS_EMPTY);
        }
    }

    /**
     * 按条件获取文章
     * @param cond
     * @param pageNum
     * @param size
     * @return
     */
    @Override
    @Cacheable(value="articleCaches",key="'articles_' + #p0 + #p0.type")
    public PageInfo<ContentDomain> getArticlesByCond(ContentCond cond, Integer pageNum, Integer size) {
        if(cond == null){
            throw SiteException.withErrorCode(ErrorConstant.Commons.PARAM_IS_EMPTY);
        }
        List<ContentDomain> articles = contentDao.getArticlesByCond(cond);
        PageHelper.startPage(pageNum,size);
        PageInfo<ContentDomain> pageInfo = new PageInfo<>(articles);
        return pageInfo;
    }

    @Override
    @Cacheable(value="articleCaches",key="'articles_'+ #p0")
    public PageInfo<ContentDomain> getRecentlyArticle(Integer pageNum, Integer size) {
        if(pageNum == null || size == null){
            throw SiteException.withErrorCode(ErrorConstant.Commons.PARAM_IS_EMPTY);
        }
        List<ContentDomain> articles = contentDao.getRecentlyArticles();
        PageHelper.startPage(pageNum,size);
        PageInfo<ContentDomain> pageInfo = new PageInfo<>(articles);
        return pageInfo;
    }

    @Override
    public PageInfo<ContentDomain> searchArticle(String param, Integer pageNum, Integer size) {
        if(StringUtils.isNotBlank(param)){
            PageHelper.startPage(pageNum,size);
            List<ContentDomain> content = contentDao.searchArticle(param);
            PageInfo<ContentDomain> pageInfo = new PageInfo<>(content);
            return pageInfo;
        }

        return null;
    }

    /**
     * 跟新文章评论数
     * @param cid
     * @param num
     */
    @Override
    @Transactional
    @CacheEvict(value={"articleCache","articleCaches"},allEntries = true,beforeInvocation = true)
    public void updateArticleCommentCount(Integer cid, Integer num) {
        if(cid == null || num == null){
            throw SiteException.withErrorCode(ErrorConstant.Commons.PARAM_IS_EMPTY);
        }
        ContentDomain contentDomain = new ContentDomain();
        contentDomain.setCid(cid);
        contentDomain.setCommentsNum(num);
        contentDao.updateArticleById(contentDomain);
    }

    @Override
    @Transactional
    @CacheEvict(value={"articleCache","articleCaches"},allEntries = true,beforeInvocation = true)
    public void updateArticleById(ContentDomain contentDomain) {
        if(contentDomain == null){
            throw SiteException.withErrorCode(ErrorConstant.Commons.PARAM_IS_EMPTY);
        }
        String tags = contentDomain.getTags();
        String categories = contentDomain.getCategories();
        int cid = contentDomain.getCid();
        metaService.addMetas(cid,tags,Types.TAG.getType());
        metaService.addMetas(cid,categories,Types.CATEGORY.getType());
    }

    @Override
    public Integer getNewArticleId() {
        return contentDao.getNewArticleId();
    }
}
